package com.wrh.springboot.restwrap;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.StringJoiner;


/**
 * @author wrh
 */
@Slf4j
public class CustomHandlerInterceptor implements HandlerInterceptor {

    private final ObjectMapper objectMapper;
    private final RestResultConfig restResultConfig;

    public CustomHandlerInterceptor(ObjectMapper objectMapper, RestResultConfig restResultConfig) {
        this.objectMapper = objectMapper;
        this.restResultConfig = restResultConfig;
    }

    // 该方法在进入Handler方法执行之前执行此方法
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//        log.debug("HandlerInterceptor：preHandle");

        // eg:   http://localhost:8080/favicon.ico
        if (handler instanceof ResourceHttpRequestHandler) {
            request.setAttribute(FinalString.REST_WRAP_IGNORE, true);
            return true;
        }

        if (((HandlerMethod) handler).getMethod().getAnnotation(RestWrapIgnore.class) != null) {
            request.setAttribute(FinalString.REST_WRAP_IGNORE, true);
            return true;
        }

        request.setAttribute(FinalString.INVOKE_START_TIMESTAMP, System.currentTimeMillis());
        request.setAttribute(FinalString.INVOKE_REST_WRAP, true);
        if (this.restResultConfig.isRestInfoEnabled()) {
            log.info("URL : {}", request.getRequestURL().toString());
            String requestMethod = request.getMethod();
            log.info("HTTP_METHOD : {}", requestMethod);
            log.info("IP : {}", request.getRemoteAddr());
            log.info("CLASS_METHOD : {}", initDescription((HandlerMethod) handler));
            if (!"POST".equals(requestMethod)) {
                log.info("ARGS : {}", objectMapper.writeValueAsString(request.getParameterMap()));
            }
        }
        return true;
    }

    // 该方法在进入Handler方法之后，返回ModelAndView之前执行
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//        log.debug("HandlerInterceptor：postHandle");
    }

    // 该方法在handler方法执行完之后执行
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//        log.debug("HandlerInterceptor：afterCompletion");
    }


    private static String initDescription(HandlerMethod handler) {
        Class<?> beanType = handler.getBeanType();
        Method method = handler.getMethod();
        StringJoiner joiner = new StringJoiner(", ", "(", ")");
        Class[] var3 = method.getParameterTypes();
        int var4 = var3.length;
        for (int var5 = 0; var5 < var4; ++var5) {
            Class<?> paramType = var3[var5];
            joiner.add(paramType.getSimpleName());
        }
        return beanType.getName() + "#" + method.getName() + joiner.toString();
    }
}
